# ifndef __ShpFile_H_
# define __ShpFile_H_

# ifdef _MSC_VER
#	pragma pack (push, 1)
# endif

const DWORD c_dwShpSignature = 0x0a270000;

enum shp_type_t {
	shpNull        = 0,
	shpPoint       = 1,
	shpPolyline    = 3,
	shpPolygon     = 5,
	shpMultiPoint  = 8,
	shpPointZ      = 11,
	shpPolylineZ   = 13,
	shpPolygonZ    = 15,
	shpMultiPointZ = 18,
	shpPointM      = 21,
	shpPolylineM   = 23,
	shpPolygonM    = 25,
	shpMultiPointM = 28,
	shpMultiPatch  = 31
};

struct CShpBox {
	double dX0;       // Bounding rectangle.
	double dY0;
	double dX1;
	double dY1;
};

struct CShpHdr {
	DWORD dwSignature;      // Always == c_dwShpSignature.

	DWORD dwaReserved1 [5]; // Fill with zero'es.

	DWORD dwFileLen;        // In WORDs, big endian!
	DWORD dwVersion;        // 1000
	DWORD dwType;           // ? shp_type_t
	CShpBox box;            // Bounding rectangle.

	double dZ0;
	double dZ1;
	double dM0;
	double dM1;
};

struct CShxRecord {
	DWORD dwOffset;  // Big endian.
	DWORD dwLen;     // In WORDs, big endian.
};

struct CShpRecordHdr {
	DWORD dwOrdinal; // 1-based, big endian.
	DWORD dwLen;     // In WORDs, big endian.
	DWORD dwType;    // From shp_type_t.
};

struct CShpNullData : public CShpRecordHdr {};

struct CShpPointData {
	double dX;
	double dY;
};

// dp@
struct CShpPointZData : public CShpPointData {
	double dZ;
	double dM;
};

struct CShpPoint : public CShpRecordHdr {
	CShpPointData point;
};

// dp@
struct CShpPointZ : public CShpRecordHdr {
	CShpPointZData point;
};

struct CShpMultiPoint : public CShpRecordHdr {
	CShpBox box;
	DWORD dwPoints;
	CShpPointData points [1];
};

struct CShpPolyline : public CShpRecordHdr {
	CShpBox box;
	DWORD dwNumParts;
	DWORD dwNumPoints;
	DWORD dwaParts [1];
	// CShpPointData points [];
};

struct CShpPolygon : public CShpRecordHdr {
	CShpBox box;
	DWORD dwNumParts;
	DWORD dwNumPoints;
	DWORD dwaParts [1];
	// CShpPointData points [];
};

enum shpMultiPatchPartType_t {
	shpMpTriangleStrip = 0,
	shpMpTriangleFan   = 1,
	shpMpOuterRing     = 2,
	shpMpInnerRing     = 3,
	shpMpFirstRing     = 4,
	shpMpRing          = 5
};

struct CShpMultiPatch : public CShpRecordHdr {
	CShpBox box;

	DWORD dwNumParts;
	DWORD dwNumPoints;
	DWORD dwaParts [1];
	// DWORD dwaPartTypes [];
	// CShpPointData points [];
	// Z and M arrays.
};

# ifdef _MSC_VER
#	pragma pack (pop)
# endif

# endif // __ShpFile_H_